Status Code 403: Spotify API, Requesting User’s Top Genre and Top Artist

I am working on a HTML, and CSS web app that uses the Spotify API. Login works great, the only problem that I have is that if I don’t add the account I’m trying to login to the user dashboard, it doesn’t work and shows an error code of “Failed to load resource: the server responded with a status of 403 ()” and “results.html?code=AQ…WKGIbYgl3eGcTtIF:89 Error fetching artist data: Check settings on developer.spotify.com/dashboard, the user may not be registered.”

index.html

<!DOCTYPE html>
<html lang="en">
<head style="background-color: #061e3e;">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Spotify Outfit - Landing Page</title>
  <link rel="stylesheet" href="LandingPage.css">
</head>
<body style="background-color: #061e3e;">
  <!-- Landing Page Section -->
  <div id="landing-page" class="landing-page">
    <div class="container">
      <h1 class="title">
        <div>YOUR</div>
        <div>SPOTIFY</div>
        <div>OUTFIT</div>
      </h1>
      <p class="subtitle">Your Outfit, Inspired by Your Music Taste</p>
      <a href="https://accounts.spotify.com/authorize?client_id=ceae01a497814f499f7aebd4830653cb&response_type=token&redirect_uri=<redacted for privacy purposes>&scope=user-read-private,user-top-read,user-read-email,user-read-recently-played,user-read-playback-state,user-read-currently-playing&state=STATE&show_dialog=true" class="connect-button">
        <img src="spotify-logo.png" alt="Spotify Logo" class="spotify-logo">
        Connect Spotify
      </a>
    </div>
  </div>

  <!-- Results Page Section (Initially Hidden) -->
  <div id="results-page" class="results-page" style="display: none;">
    <div class="container">
      <h2>Your Top Genre:</h2>
      <p id="genre-name">Loading...</p>
      <h3>Your Top Artist:</h3>
      <p id="artist-name"></p>
      <img id="artist-image" src="outfit-placeholder.png" alt="Top Artist Image" class="artist-image">
    </div>
  </div>

  <script>
    

    // Function to extract access token from URL
    function getAccessTokenFromURL() {
      const hash = window.location.hash.substring(1);
      const params = new URLSearchParams(hash);
      return params.get("access_token");
    }

    // Fetch user's top artist data from Spotify
        function getAccessTokenFromURL() {
            var accessToken = null;
            var hash = window.location.hash.substring(1);
            var params = hash.split('&');
            for (var i = 0; i < params.length; i++) {
                var param = params[i].split('=');
                if (param[0] === 'access_token') {
                    accessToken = param[1];
                    break;
                }
            }
            return accessToken;
        }
        // Check if the URL contains an access token
        window.addEventListener("load", function() {
            var accessToken = getAccessTokenFromURL();
            if (accessToken) {
                // If access token is present, store it in sessionStorage
                sessionStorage.setItem('accessToken', accessToken);
                // Redirect to the main page or perform other actions
                window.location.href = <redacted for privacy purposes>
            }
        });
   
  </script>
</body>
</html>

results.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Spotify Outfit - Results Page</title>
  <link rel="stylesheet" href="ResultsPage.css">
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script>
 document.addEventListener("DOMContentLoaded", function() {
    var clientId = 'ceae01a497814f499f7aebd4830653cb'; // Replace with your actual client_id
    var clientSecret = <redacted for privacy purposes>
  const redirectUri = <redacted for privacy purposes>

    const urlParams = new URLSearchParams(window.location.search);
    const authCode = urlParams.get('code');
    console.log("Auth Code:", authCode); // Check if the code is present

    if (authCode) {
        exchangeCodeForToken(authCode);
    } else {
        redirectToSpotifyAuth();
    }

    function redirectToSpotifyAuth() {
        const scopes ='user-read-private user-read-email user-read-playback-state user-modify-playback-state user-read-recently-played user-top-read';
        const authUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scopes)}`;
        window.location.href = authUrl;
    }

    function exchangeCodeForToken(code) {
        $.ajax({
            url: "https://accounts.spotify.com/api/token",
            type: "POST",
            headers: {
                "Authorization": "Basic " + btoa(`${clientId}:${clientSecret}`)
            },
            data: {
                grant_type: "authorization_code",
                code: code,
                redirect_uri: redirectUri
            },
            success: function(response) {
                console.log("Access Token Response:", response);
                const accessToken = response.access_token;
                fetchUserTopArtistAndGenre(accessToken);
            },
            error: function(xhr, status, error) {
                console.error("Error exchanging code for token:", xhr.responseText || error);
            }
        });
    }

    function fetchUserTopArtistAndGenre(accessToken) {
        $.ajax({
            url: "https://api.spotify.com/v1/me/top/artists?time_range=short_term&limit=1",
            type: "GET",
            headers: {
                "Authorization": "Bearer " + accessToken
            },
            success: function(response) {
                console.log("API Response:", response);
                const mainGenreElement = $('#mainGenre');
                const artistContainer = $('#artist-container');
                const artistNameElement = $('#artistName');
                const artistImageElement = $('#artistImage');

                if (response.items.length > 0) {
                    const topArtist = response.items[0];
                    const genres = topArtist.genres;
                    const artistName = topArtist.name;
                    const artistImage = topArtist.images.length > 0 ? topArtist.images[0].url : null;

                    const mainGenre = genres.length > 0 ? genres[0] : "No genre available";
                    mainGenreElement.text(mainGenre);
                    artistNameElement.text(artistName);
                    if (artistImage) {
                        artistImageElement.attr('src', artistImage).show();
                    } else {
                        artistImageElement.hide();
                    }
                    artistContainer.show();
                } else {
                    mainGenreElement.text("No genre available.");
                    artistContainer.hide();
                }
            },
            error: function(xhr, status, error) {
                console.error("Error fetching artist data:", xhr.responseText || error);
            }
        });
    }
});
</script>
</head>
<body>

    <div class="results-page">
        <div class="results-container">
            <h1 class="main-genre">Your main genre is...</h1>
            <h2 id="mainGenre" class="genre">Loading...</h2>

            <div id="artist-container" class="artist-container" style="display: none;">
                <h3 class="artist-title">Your Top Artist:</h3>
                <p id="artistName" class="artist-name"></p>
                <img id="artistImage" alt="Top Artist" class="artist-image" style="width: 200px; height: auto; border-radius: 10px;" />
            </div>
        <h3 class="outfit-title">Here is your outfit!</h3>
      <img id="outfit-image" src="outfit-placeholder.png" alt="Outfit" class="outfit-image" />
        </div>
    </div>
</body>
</html>

Initially, I thought it was the scope parameters because it was set to user-read-private, I added the ones I think I needed (‘user-read-private user-read-email user-read-playback-state user-modify-playback-state user-read-recently-played user-top-read’) and it still didn’t work out for me. So, I’m quite stuck as someone newer to this.