Getting 400 Error with Spotify Web API Authentication in Python

Hey everyone! I’m working on a Python project that connects to the Spotify Web API but I keep getting a 400 error saying “Only valid bearer authentication supported”. The authentication part seems to work fine and returns True, but when I try to make the actual API call it fails.

import base64, requests
import datetime
from urllib.parse import urlencode

app_id = "your_app_id"
app_secret = "your_app_secret"

class MusicAPI(object):
    token = None
    token_expires = datetime.datetime.now()
    token_expired = True
    app_id = None
    app_secret = None
    auth_url = "https://accounts.spotify.com/api/token"

    def __init__(self, app_id, app_secret, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.app_id = app_id
        self.app_secret = app_secret

    def encodeCredentials(self):
        app_id = self.app_id
        app_secret = self.app_secret
        
        if app_id == None or app_secret == None:
            raise Exception('App ID and secret required')
        
        credentials = f"{app_id}:{app_secret}"
        encoded_creds = base64.b64encode(credentials.encode())
        return encoded_creds.decode()

    def buildAuthHeader(self):
        encoded_creds = self.encodeCredentials()
        return {
            'Authorization': f"Basic {encoded_creds}"
        }

    def buildTokenData(self):
        return {
            "grant_type": "client_credentials"
        }

    def authenticate(self):
        auth_url = self.auth_url
        token_data = self.buildTokenData()
        auth_header = self.buildAuthHeader()
        
        response = requests.post(auth_url, data=token_data, headers=auth_header)
        
        if response.status_code not in range(200, 299):
            return False
        
        current_time = datetime.datetime.now()
        response_data = response.json()
        access_token = response_data['access_token']
        expires_in = response_data['expires_in']
        expiry_time = current_time + datetime.timedelta(seconds=expires_in)
        
        self.token = access_token
        self.token_expires = expiry_time
        self.token_expired = expiry_time < current_time
        
        return True

music_client = MusicAPI(app_id, app_secret)
print(music_client.authenticate())
user_token = music_client.token

request_header = {
    "Authorization": f"Bearer {user_token}"
}

api_endpoint = "https://api.spotify.com/v1/search"
query_params = urlencode({"q": "Hello", "type": "track"})
full_url = f"{api_endpoint}?{query_params}"

api_response = requests.get(full_url, headers=request_header)
print(api_response.json())

The output shows:

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

Can anyone spot what I’m doing wrong? Any help would be appreciated!

ur token’s probably None when u hit the API. same thing happened 2 me - auth worked fine but the token was empty. print user_token right b4 the request to see if it has a value. sometimes response.json() doesn’t have that access_token key ur looking for.

Your token probably isn’t getting extracted or stored right during auth. Had the exact same issue building a track analysis tool last year.

Your authenticate method returns True even when token extraction fails silently. The response might be successful, but the JSON structure could be different than expected. Add some debugging right after response_data = response.json() to see what you’re actually getting back.

Also check if you’re calling authenticate before every API request. Client credentials tokens expire and need refresh, but you’re only authenticating once at the start. Any delay between auth and API call means your token state might not be what you think.

I’d add a wrapper method that checks token validity and re-authenticates if needed before each API call. Don’t rely on that initial auth state staying valid throughout your program.

Your token auth probably works fine initially, but breaks when you’re making multiple API calls or dealing with token refresh. Manual token management gets messy real quick.

I hit this exact issue last year building a music recommendation system. Token worked at first, then failed randomly. Debugging auth flows manually was a total nightmare.

What fixed it for me was switching to Latenode for the whole Spotify API workflow. Instead of juggling tokens, expiry times, and error handling in Python, I just set up the auth and API calls as automated workflows.

Latenode handles OAuth automatically, refreshes tokens when needed, and gives you clean endpoints to call from Python. You send your search query to the Latenode workflow, it returns Spotify data. No auth headaches.

You can also add error handling, rate limiting, and response caching right in the workflow. No more 400 errors or token management code cluttering your main app.

Auth becomes bulletproof since Latenode manages everything. Your Python code just focuses on using the data instead of fighting with API authentication.

Your code isn’t checking if the token expired before using it. You set token_expired during auth but never update it when the token actually dies.

I hit the same thing building a playlist analyzer. Token worked fine at first, then started failing after a while. I was storing the expiry time but wasn’t checking it before API calls.

Add a validation method that checks if current time passed your stored expiry. If it did, re-auth automatically before the API request. Just check if datetime.datetime.now() >= self.token_expires before each call.

Also, your token_expired logic is backwards. You’re comparing expiry to current time right after setting it - that’ll always be False since expiry is in the future. Only mark it expired when current time actually exceeds expiry time.