Getting grant_type error when authenticating with Spotify Web API

I’m trying to authenticate with Spotify’s Web API using client credentials flow but keep running into issues. Every time I make the authentication request, I get a 400 error saying the grant_type is unsupported, even though I’m setting it to client_credentials like the docs say.

The error message I keep getting is:

400 Bad Request: {"error":"unsupported_grant_type","error_description":"grant_type must be client_credentials, authorization_code or refresh_token"}

Here’s my authentication function:

sub fetch_auth_token {
    my $params = {grant_type => "client_credentials"};
    
    my $request = HTTP::Request->new("POST", TOKEN_ENDPOINT, [
        "Content-Type" => "application/x-www-form-urlencoded",
        "Authorization" => "Basic $ENV{SPOTIFY_AUTH_B64}",
    ], encode_utf8 encode_json $params);
    
    my $response = $ua->request($request);
    
    if($response->is_success) {
        return %{decode_json $response->content}{"access_token"};
    } else {
        die $response->status_line . ": " . $response->content . "\n";
    }
}

I’ve double checked my client credentials and they seem correct. What could be causing this grant_type error?

The issue lies in the request body encoding. You’re currently using encode_json to send the parameters, but Spotify’s token endpoint requires form-encoded data instead of JSON. Although the Content-Type header is correctly set to application/x-www-form-urlencoded, the request body format is incorrect.

You should replace the line encoding the request body with something like this:

], "grant_type=client_credentials");

Alternatively, consider using URI::Encode or a similar method to ensure your parameters are properly form-encoded. The API cannot interpret the grant_type when it receives a JSON body, leading to the error you’re encountering. This mismatch between content type and actual data format is a frequent issue with REST APIs.