# Extension Chat Message returns 401 authentication failed

**URL:** <https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686>\
**Category:** Extensions\
**Created:** [June 23, 2020, 2:19pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686 "2020-06-23T14:19:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sidar\_O](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/sidar_o/32/9334_2.png) [@Sidar\_O](https://discuss.dev.twitch.com/u/Sidar_O)\
**Post date:** [June 23, 2020, 2:19pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/1 "2020-06-23T14:19:30Z")

</div>

Hi, When a viewer used my extension , extension should send a message to chat about that user in that channel. Just want to send a simple message.

I’m working on “[send extension chat message](https://dev.twitch.tv/docs/extensions/reference/#send-extension-chat-message)” also i tried “[Send Extension PubSub Message](https://dev.twitch.tv/docs/extensions/reference/#send-extension-pubsub-message)” too. When i tried pubsub i was getting “403 - JWT could not be verified” error and i cant figure out it. Now i’m trying other way but i’m getting “401 authentication failed” error.  
I have read a lot of explanations and posts on this subject and tried a lot of things. I am very confused now.

EBS is writen in PHP.

> $payload\_arr = array(   
> “exp” =\> $time,  
> “user\_id”=\> $channelid,  
> “role”=\> “external”  
> );
> 
> $payload = json\_encode($payload\_arr);  
> // {“exp”:1592921206,“user\_id”:“49354541”,“role”:“external”}
> 
> $jwt = JWT::encode($payload, $secretkey);
> 
> // I also check the token at [jwt.io](https://jwt.io/) too.
> 
> //Send Extension Chat Message
> 
> $url = “[https://api.twitch.tv/extensions/“.$clientid.”/“.$clientversion.”/channels/“.$channelid.”/chat](https://api.twitch.tv/extensions/%22.$clientid.%22/%22.$clientversion.%22/channels/%22.$channelid.%22/chat)”;  
> $headers = array(  
> "Authorization: Bearer ".(string)$jwt,  
> "Client-Id: ".$clientid,  
> “Content-Type: application/json”  
> );
> 
> $data = array(“text” =\> ‘Extension send a message to chat’);
> 
> $ch = curl\_init($url);  
> curl\_setopt($ch, CURLOPT\_POST, true);  
> curl\_setopt($ch, CURLOPT\_POSTFIELDS, json\_encode($data));  
> curl\_setopt($ch, CURLOPT\_RETURNTRANSFER, true);  
> curl\_setopt($ch, CURLOPT\_HTTPHEADER, $headers);  
> curl\_setopt($ch, CURLINFO\_HEADER\_OUT, true);  
> curl\_exec($ch);  
> $dresp = curl\_exec($ch);  
> $info = curl\_getinfo($ch);  
> curl\_close($ch);

Request Header:

> [request\_header] =\> POST /extensions/89sl308o9vzckjsz2viv6mx76ihask/1.1.1/channels/49354541/chat HTTP/2  
> Host: [api.twitch.tv](http://api.twitch.tv)  
> accept: _/_  
> authorization: Bearer [token]  
> client-id: 89sl308o9vzckjsz2viv6mx76ihask  
> content-type: application/json  
> content-length: 37

Response;

> {“error”:“Unauthorized”,“status”:401,“message”:“authentication failed”}

What am i doing wrong. Thanks for help.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [June 23, 2020, 2:26pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/2 "2020-06-23T14:26:07Z")

</div>

Is the extension of the same version installed and active on the channel?  
Has the streamer got the chat option enabled?

![image](https://d2opxh93rbxzdn.cloudfront.net/original/2X/c/cba317f8ac80c215f19f0aac41934d25b43111c4.png)

```
https://dashboard.twitch.tv/u/STREAMERNAME/extensions/permissions

```

---

<div class="post-metadata">

**Author:** ![Sidar\_O](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/sidar_o/32/9334_2.png) [@Sidar\_O](https://discuss.dev.twitch.com/u/Sidar_O)\
**Post date:** [June 23, 2020, 2:36pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/3 "2020-06-23T14:36:37Z")

</div>

Yes it’is installed on my channel for testing and also chat options enabled.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [June 23, 2020, 2:47pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/4 "2020-06-23T14:47:23Z")

</div>

Oh you did base64 decode your extension secret before using it to encode the JWT?

The only thing I do different is for pubsub I use, (javascript but easy enough to convert to PHP)

```auto
const sigPubSubPayload = {
    "exp": Math.floor(new Date().getTime() / 1000) + 60,
    "user_id": config.owner,
    "role": "external",
    "channel_id": "all",
    "pubsub_perms": {
        "send": [
            "global"
        ]
    }
}

```

And chat

```auto
    var sigPayload = {
        'exp': Math.floor(new Date().getTime() / 1000) + 60,
        'user_id': config.twitch.streamer_id,
        'role': 'broadcaster'
    }

```

Since you’ve tried both PubSub and chat, and got the same issue, I bet you forgot (or didn’t know) to base decode your secret before passing it to the encoder

---

<div class="post-metadata">

**Author:** ![Sidar\_O](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/sidar_o/32/9334_2.png) [@Sidar\_O](https://discuss.dev.twitch.com/u/Sidar_O)\
**Post date:** [June 23, 2020, 2:57pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/5 "2020-06-23T14:57:46Z")

</div>

This is the class i used for JWT encode.  
Also i copied jwt code and paste to [jwt.io](http://jwt.io) for check payload data. On that site its decoded like this.

> {"exp":1592923080,"user\_id":"49354541","role":"external"}"

so it’ll be about base64 encode/decode. Going to check that.

> public static function encode($payload, $key, $alg = ‘HS256’, $keyId = null, $head = null)  
> {  
> $header = array(‘typ’ =\> ‘JWT’, ‘alg’ =\> $alg);
> 
> ```
> if ($keyId !== null) {
> $header['kid'] = $keyId;
> }
> 
> if ( isset($head) && is_array($head) ) {
> $header = array_merge($head, $header);
> }
> 
> $segments = array();
> $segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
> $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
> $signing_input = implode('.', $segments);
> $signature = static::sign($signing_input, $key, $alg);
> $segments[] = static::urlsafeB64Encode($signature);
> 
> return implode('.', $segments);
> }
> 
> ```

> ```
> public static function sign($msg, $key, $alg = 'HS256')
> {
> if (empty(static::$supported_algs[$alg])) {
> throw new Exception('Algorithm not supported');
> }
> list($function, $algorithm) = static::$supported_algs[$alg];
> switch($function) {
> case 'hash_hmac':
> return hash_hmac($algorithm, $msg, $key, true);
> case 'openssl':
> $signature = '';
> $success = openssl_sign($msg, $signature, $key, $algorithm);
> if (!$success) {
> throw new Exception("OpenSSL unable to sign data");
> } else {
> return $signature;
> }
> }
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![Sidar\_O](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/sidar_o/32/9334_2.png) [@Sidar\_O](https://discuss.dev.twitch.com/u/Sidar_O)\
**Post date:** [June 24, 2020, 11:14am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/6 "2020-06-24T11:14:29Z")

</div>

I’m using **extension secret** at **extension client configuration.**

> I’ll delete key.  
> $base64key=“ **REMOVED** =”; // base64 encoded key  
> $decodedkey = base64\_decode($base64key);  
> printed : �����,qE�-��5�٭�2Q?"'z��7

base64 decode returns key with invalid characters. I created new extension secret but it returns invalid too.

Also I’m getting 401 error with that undecoded key too.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [June 24, 2020, 11:59am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/7 "2020-06-24T11:59:05Z")

</div>

Removed your key as it counts as a password and shouldn’t be posted publically.

Try this instead, confirmed as working having just tested it, (it’s a bad/old/dumb test script for the chat endpoint I have kicking about in PHP)

For this `$user_id` should be the ID of the channel that you want to send Chat messages to.

```auto
<?php

echo date('r', time());
echo "\n";

$client_id = 'CLIENID';
$secret = base64_decode('SECRET');
$version = '0.0.1';
$user_id = 'CHANNEL_ID';

// end edits

include( __DIR__. '/jwt.php');
$j = new JWT();

$payload = array(
    'exp' => time() + 60,
    'user_id' => ''.$user_id,
    'role' => 'broadcaster'
);
$bearer = $j->encode($payload, $secret);

echo "\n" . $bearer . "\n";

$data_string = json_encode(array(
    'text' => 'This is a test'
));

$url = 'https://api.twitch.tv/extensions/' . $client_id . '/' . $version . '/channels/' . $user_id . '/chat';

echo $url;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_ENCODING , "gzip");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Authorization: Bearer ' . $bearer,
    'Client-ID: ' . $client_id,
    'Content-Type: application/json'
));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);

$r = curl_exec($ch);
$i = curl_getinfo($ch);

curl_close($ch);

echo "\n" . $i['http_code'] . "\n";

echo "\n";
echo $r;
echo "\n";

```

jwt.php is from [https://github.com/firebase/php-jwt/blob/master/src/JWT.php](https://github.com/firebase/php-jwt/blob/master/src/JWT.php)

But my current version of the file is, I only tested against my version as I know it works

> <https://gist.github.com/BarryCarlyon/d234c3774e3b1b297440a47457ddf965>

Most notably is my payload differs

```auto
$payload = array(
    'exp' => time() + 60,
    'user_id' => ''.$user_id,
    'role' => 'broadcaster'
);

```

However

```auto
$payload = array(
    'exp' => time() + 60,
    'user_id' => '15185913',
    'role' => 'external'
);

```

Also works (my user\_id and I own the extension posting to another channel)

+60 for the exp is _SUPER LIBERAL_ really too

---

<div class="post-metadata">

**Author:** ![Sidar\_O](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/sidar_o/32/9334_2.png) [@Sidar\_O](https://discuss.dev.twitch.com/u/Sidar_O)\
**Post date:** [June 24, 2020, 12:59pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/8 "2020-06-24T12:59:56Z")

</div>

I checked your code and compare with mine.

I found the problem. I was encode the payload with json before create JWT.

Now it works. Thanks for help.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [June 24, 2020, 1:01pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/9 "2020-06-24T13:01:03Z")

</div>

> [@Sidar\_O](#):
>
> Now it works. Thanks for help.

Welcome.

Probably also worth _just using_ the JWT lib I linked rather than custom code, but if your stuff works all the better!

---

<div class="post-metadata">

**Author:** ![tejendrapratap12](https://avatars.discourse-cdn.com/v4/letter/t/cab0a1/32.png) [@tejendrapratap12](https://discuss.dev.twitch.com/u/tejendrapratap12)\
**Post date:** [March 15, 2022, 11:19am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/10 "2022-03-15T11:19:41Z")

</div>

Hey, I am getting

```auto
{
    "error": "Unauthorized",
    "status": 401,
    "message": "authentication failed"
}

```

Do we need to create our own JWT to call this API? or can we use the auth token provided to us in `onAuthorized` method?

@BarryCarlyon

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [March 15, 2022, 11:33am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/11 "2022-03-15T11:33:22Z")

</div>

> [@tejendrapratap12](#):
>
> Do we need to create our own JWT to call this API? or can we use the auth token provided to us in `onAuthorized` method?

I believe only a broadcasters token is valid for sending to their own chat.

The documentation for the end point says you need to use an external JWT. So you should generate your own JWT

> **[Reference](https://dev.twitch.tv/docs/api/reference/)**
>
> Twitch Developer tools and services to integrate Twitch into your development or create interactive experience on twitch.tv.

Recommends the usage of an external

---

<div class="post-metadata">

**Author:** ![tejendrapratap12](https://avatars.discourse-cdn.com/v4/letter/t/cab0a1/32.png) [@tejendrapratap12](https://discuss.dev.twitch.com/u/tejendrapratap12)\
**Post date:** [March 15, 2022, 11:34am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/12 "2022-03-15T11:34:09Z")

</div>

Oh okay, And the secret to sign this JWT will be the client secret right?

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [March 15, 2022, 11:34am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/13 "2022-03-15T11:34:35Z")

</div>

> [@tejendrapratap12](#):
>
> the secret to sign this JWT will be the client secret right?

No.

It’s the Extension Secret, not the Twitch API Client Secret

---

<div class="post-metadata">

**Author:** ![tejendrapratap12](https://avatars.discourse-cdn.com/v4/letter/t/cab0a1/32.png) [@tejendrapratap12](https://discuss.dev.twitch.com/u/tejendrapratap12)\
**Post date:** [March 15, 2022, 11:37am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/14 "2022-03-15T11:37:22Z")

</div>

This is the one right?

 ![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/1/7/172ea7e479cf5c0653ae369e641a917d81588e98.png)

I am using this code to generate the Jwt to call the api but still getting the same error.

```auto
const sec = "secret from above image";
const secret = Buffer.from(sec, "base64");
app.post("/getJWTToken", (req, res) => {
  let data = {
    channel_id: 768266494,
    role: "external",
  };

  const token = jsonwebtoken.sign(data, secret);
  res.send(token);
});

```

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [March 15, 2022, 11:39am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/15 "2022-03-15T11:39:01Z")

</div>

You need to cast the channelID as a _string_ not a _number_

> [@BarryCarlyon](#):
>
> However
> 
> ```auto
> $payload = array(
> 'exp' => time() + 60,
> 'user_id' => '15185913',
> 'role' => 'external'
> );
> 
> ```
> 
> Also works (my user\_id and I own the extension posting to another channel)

> <https://github.com/BarryCarlyon/twitch_misc/tree/main/extensions/chat>
>
> //github.com/BarryCarlyon/twitch\_misc/tree/main/extensions/chat

So

```auto
const sigChatPayload = {
    "exp": Math.floor(new Date().getTime() / 1000) + 4,
    "user_id": "123123",
    "role": "external"
}
const sigChat = jwt.sign(sigChatPayload, ext_secret);

// We have now prepared the Signature and data

got({
    url: "https://api.twitch.tv/helix/extensions/chat",
    method: "POST",
    headers: {
        "Client-ID": config.client_id,
        "Authorization": "Bearer " + sigChat
    },
    json: {
        broadcaster_id: "321321",
        text: "This is a Test Message Kappa",
        extension_id: config.client_id,
        extension_version: config.extension_version
    },
    responseType: 'json'
})

```

Also

> [@tejendrapratap12](#):
>
> ```auto
> app.post("/getJWTToken", (req, res) => {
> let data = {
> channel_id: 768266494,
> role: "external",
> };
> 
> const token = jsonwebtoken.sign(data, secret);
> res.send(token);
> });
> 
> ```

This seems dangerous. It looks like you are intending to leak generated JWT’s which is potentially dangerous to do so.

---

<div class="post-metadata">

**Author:** ![tejendrapratap12](https://avatars.discourse-cdn.com/v4/letter/t/cab0a1/32.png) [@tejendrapratap12](https://discuss.dev.twitch.com/u/tejendrapratap12)\
**Post date:** [March 21, 2022, 6:48am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/16 "2022-03-21T06:48:19Z")

</div>

Hey @BarryCarlyon I tried this

```auto
const sec = "mysecret_key";
const secret = Buffer.from(sec, "base64");
const bearerPrefix = "Bearer ";

const sigChatPayload = {
  exp: Math.floor(new Date().getTime() / 1000) + 4,
  channel_id: "152826156",
  role: "external",
};

const sigChat = jsonwebtoken.sign(sigChatPayload, secret);
const client_id = "y7aqa290cuap0tqrvs44t3wr9qu20f";
got({
  url: "https://api.twitch.tv/helix/extensions/chat",
  method: "POST",
  headers: {
    "Client-ID": client_id,
    Authorization: "Bearer " + sigChat,
  },
  json: {
    broadcaster_id: 152826156,
    text: "This is a Test Message Kappa",
    extension_id: client_id,
    extension_version: "0.0.1",
  },
  responseType: "json",
})
  .then((resp) => {
    // console log out the useful information
    // keeping track of rate limits is important
    // you can only set the config 12 times a minute per segment
    console.error(
      "Send Chat OK",
      resp.statusCode,
      resp.headers["ratelimit-remaining"],
      "/",
      resp.headers["ratelimit-limit"]
    );

    // we don't care too much about the statusCode here
    // but you should test it for a 204
  })
  .catch((err) => {
    if (err.response) {
      console.error("Errored", err.response.statusCode, err.response.body);
      return;
    }
    console.error(err);
  });

```

But still getting

 ![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/7/e/7e6991eec55f22f52f1a02247132084ccdbc9479.png)

I am live on the broadcaster channel and have the extension installed there as well

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [March 21, 2022, 11:51am UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/17 "2022-03-21T11:51:25Z")

</div>

You did the the _extension secret_ and not the _extension client secret_

The bottom one:

 ![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/4/3/43d8befb119670f2390c99b79e6099161bd43516.png)

For ease of testing lets also change

```auto
const sigChatPayload = {
  exp: Math.floor(new Date().getTime() / 1000) + 4,
  channel_id: "152826156",
  role: "external",
};

```

to

```auto
const sigChatPayload = {
  exp: Math.floor(new Date().getTime() / 1000) + 4,
  user_id: "The ID of the Twitch Account that owns the extension",
  role: "external",
};

```

and the broadcaster\_id in the payload is not correct

```auto
  json: {
    broadcaster_id: 152826156,
    text: "This is a Test Message Kappa",
    extension_id: client_id,
    extension_version: "0.0.1",
  },

```

should be a string

```auto
  json: {
    broadcaster_id: "152826156",
    text: "This is a Test Message Kappa",
    extension_id: client_id,
    extension_version: "0.0.1",
  },

```

Also check the version numbers match. That 0.0.1 is active on the destination channel

---

<div class="post-metadata">

**Author:** ![tejendrapratap12](https://avatars.discourse-cdn.com/v4/letter/t/cab0a1/32.png) [@tejendrapratap12](https://discuss.dev.twitch.com/u/tejendrapratap12)\
**Post date:** [March 21, 2022, 12:01pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/18 "2022-03-21T12:01:09Z")

</div>

- I am using Extension Client Configuration
- changed the channel\_id to user\_id and set it to the id of the twitch account that owns the extension
- Made the broadcaster\_id value to be a string

Still getting the same error

 ![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/d/a/daa93ced01a0e3f21bb436a2ea481f8b7192797b.png)

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [March 21, 2022, 12:04pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/19 "2022-03-21T12:04:20Z")

</div>

The extension does have the capability enabled:

 ![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/b/8/b868f93f718ed736251ee71393204cfce08da1ec.png)

And “Chat” is enabled in the streamer permissions

![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/2/f/2f07ea6d56e69ac6e94f8eed74c8e5d02ea6f0a1.png)

This is on [Creator Dashboard](https://dashboard.twitch.tv/extensions) then click `My Extensions` then `Manage Permissions` alternativelly uninstall and reinstall the extension (not unactivate and reactivate)

---

<div class="post-metadata">

**Author:** ![tejendrapratap12](https://avatars.discourse-cdn.com/v4/letter/t/cab0a1/32.png) [@tejendrapratap12](https://discuss.dev.twitch.com/u/tejendrapratap12)\
**Post date:** [March 21, 2022, 12:13pm UTC](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686/20 "2022-03-21T12:13:39Z")

</div>

Thank you @BarryCarlyon . It works now.

[Next page](https://discuss.dev.twitch.com/t/extension-chat-message-returns-401-authentication-failed/26686.md?page=2)
