Home > database >  Spotify API Client Credentials Flow returning 400 error
Spotify API Client Credentials Flow returning 400 error

Time:10-01

Using Spotify Documentation for Client Credential Flow Client Credential Image

Yet, when I run this code, I get this error

{ error: 
   { status: 400,
     message: 'Only valid bearer authentication supported' } }

If, I'm am using client credential flow, why does it think I am using a bearer token? (Also if I change authentication to Bearer I get a 401 error "Invalid access token")

2). Could you provide an example of a working version of this code and why it was able to run opposed to mine?

CodePudding user response:

I believe your goal is as follows.

  • You want to convert the following curl command to Google Apps Script.

      curl -X "POST" -H "Authorization: Basic ZjM4ZjAw...WY0MzE=" -d grant_type=client_credentials https://accounts.spotify.com/api/token
    

In this case, grant_type=client_credentials is sent as the form data. When I saw your script, it is sent as the data. And you use the URL of https://api.spotify.com/api/token. But the curl command uses https://accounts.spotify.com/api/token. `I thought that these might be the reason for your issue. So when your script is modified, it becomes as follows.

Modified script:

function callAPI() {
  SPOTIFY_CLIENT_SECRET = secret; // Please set your value.
  SPOTIFY_CLIENT_ID = id; // Please set your value.
  const HEADERS = {
    'Authorization': `Basic ${Utilities.base64Encode(SPOTIFY_CLIENT_ID   ':'   SPOTIFY_CLIENT_SECRET)}` // Modified
  }
  const BODY = {
    'grant_type': 'client_credentials'
  }
  var url = "https://accounts.spotify.com/api/token";
  var requestOptions = {
    'method': 'POST',
    'headers': HEADERS,
    'payload': BODY,
    'muteHttpExceptions': true,
  };
  var response = UrlFetchApp.fetch(url, requestOptions);
  var data = response.getContentText();
  console.log(data)
}

Note:

  • When I saw your script again, I noticed that Basic ${Utilities.base64Encode(SPOTIFY_CLIENT_ID ':' SPOTIFY_CLIENT_SECRET)}) is required to be modified. Because in this case, it's Basic ###). Please remove ).

References:

CodePudding user response:

I figured it out! For some reason you need to add the client id and client secret in the form data. The Spotify docs says to put them in the headers base64 encoded but that is not the case in this instance. (You don't even need to encode them)

Also you don't even need to include the content-type parameter like the doc says.

working code looks like this

  function callAPI () {
    let SPOTIFY_CLIENT_SECRET = secret
    let SPOTIFY_CLIENT_ID = id

  const BODY = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'grant_type': 'client_credentials',
    "client_id": SPOTIFY_CLIENT_ID,
    "client_secret": SPOTIFY_CLIENT_SECRET,
  }

  var url = "https://accounts.spotify.com/api/token";
  
  var requestOptions = {
    'method': 'POST',
    'payload': BODY,
    'muteHttpExceptions': true,
  };

  var response = UrlFetchApp.fetch(url, requestOptions);
  var data = response.getContentText();
  console.log(data)

  }

I found my answer from reading about a similar problem here

  • Related