<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Help with Error 403 while getting top tracks in Spotify for Developers</title>
    <link>https://community.spotify.com/t5/Spotify-for-Developers/Help-with-Error-403-while-getting-top-tracks/m-p/6012379#M13551</link>
    <description>&lt;P&gt;According to &lt;A href="https://developer.spotify.com/documentation/web-api/reference/get-users-top-artists-and-tracks" target="_blank" rel="noopener"&gt;this documentation&lt;/A&gt;, you should add the&amp;nbsp;&lt;EM&gt;user-top-read&lt;/EM&gt; scope.&lt;/P&gt;</description>
    <pubDate>Wed, 17 Apr 2024 16:45:15 GMT</pubDate>
    <dc:creator>Ximzend</dc:creator>
    <dc:date>2024-04-17T16:45:15Z</dc:date>
    <item>
      <title>Help with Error 403 while getting top tracks</title>
      <link>https://community.spotify.com/t5/Spotify-for-Developers/Help-with-Error-403-while-getting-top-tracks/m-p/6011510#M13546</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;const clientId = "...";
const params = new URLSearchParams(window.location.search);
const code = params.get("code");

if (!code) {
    redirectToAuthCodeFlow(clientId);
} else {
    const accessToken = await getAccessToken(clientId, code);
    const profile = await fetchProfile(accessToken);
    const tracks = await fetchTracks(accessToken);
    populateUI(profile, tracks);
}

export async function redirectToAuthCodeFlow(clientId: string) {
    const verifier = generateCodeVerifier(128);
    const challenge = await generateCodeChallenge(verifier);
    
    localStorage.setItem("verifier", verifier);
    
    const params = new URLSearchParams();
    params.append("client_id", clientId);
    params.append("response_type", "code");
    params.append("redirect_uri", "http://localhost:5173/callback");
    params.append("scope", "user-read-private user-read-email");
    params.append("code_challenge_method", "S256");
    params.append("code_challenge", challenge);
    
    document.location = `https://accounts.spotify.com/authorize?${params.toString()}`;
}
    
function generateCodeVerifier(length: number) {
    let text = '';
    let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    for (let i = 0; i &amp;lt; length; i++) {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }
    return text;
}

async function generateCodeChallenge(codeVerifier: string) {
    const data = new TextEncoder().encode(codeVerifier);
    const digest = await window.crypto.subtle.digest('SHA-256', data);
    return btoa(String.fromCharCode.apply(null, [...new Uint8Array(digest)]))
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=+$/, '');
}


export async function getAccessToken(clientId: string, code: string): Promise&amp;lt;string&amp;gt; {
    const verifier = localStorage.getItem("verifier");

    const params = new URLSearchParams();
    params.append("client_id", clientId);
    params.append("grant_type", "authorization_code");
    params.append("code", code);
    params.append("redirect_uri", "http://localhost:5173/callback");
    params.append("code_verifier", verifier!);

    const result = await fetch("https://accounts.spotify.com/api/token", {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: params
    });

    const { access_token } = await result.json();
    return access_token;
}

async function fetchProfile(token: string): Promise&amp;lt;UserProfile&amp;gt; {
    const result = await fetch("https://api.spotify.com/v1/me", {
        method: "GET", headers: { Authorization: `Bearer ${token}` }
    });

    return await result.json();
} 


async function fetchTracks(token: string): Promise&amp;lt;any&amp;gt; {
    const result = await fetch("https://api.spotify.com/v1/me/top/tracks", {
        method: "GET", headers: { Authorization: `Bearer ${token}` }
    });

    return await result.json();
} 


function populateUI(profile: UserProfile, tracks: any) {
    document.getElementById("displayName")!.innerText = profile.display_name;
    if (profile.images[0]) {
        const profileImage = new Image(200, 200);
        profileImage.src=profile.images[0].url;
        document.getElementById("avatar")!.appendChild(profileImage);
    }
    document.getElementById("id")!.innerText = profile.id;
    document.getElementById("email")!.innerText = profile.email;
    document.getElementById("uri")!.innerText = profile.uri;
    document.getElementById("uri")!.setAttribute("href", profile.external_urls.spotify);
    document.getElementById("url")!.innerText = profile.href;
    document.getElementById("url")!.setAttribute("href", profile.href);
    document.getElementById("imgUrl")!.innerText = profile.images[0]?.url ?? '(no profile image)';
 
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;First time working with the Spotify API, I followed the tutorial on the api page and the profile data displaying went fine. But I am getting an error 403 on the top tracks call even tho when I go to the link "&lt;/SPAN&gt;&lt;A class="" href="https://api.spotify.com/v1/me/top/tracks" target="_blank" rel="noopener nofollow ugc noreferrer"&gt;https://api.spotify.com/v1/me/top/tracks&lt;/A&gt;&lt;SPAN&gt;" after logging in I get the tracks data just fine. Why is the call not working in my app?&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 17 Apr 2024 07:15:56 GMT</pubDate>
      <guid>https://community.spotify.com/t5/Spotify-for-Developers/Help-with-Error-403-while-getting-top-tracks/m-p/6011510#M13546</guid>
      <dc:creator>Ham25</dc:creator>
      <dc:date>2024-04-17T07:15:56Z</dc:date>
    </item>
    <item>
      <title>Re: Help with Error 403 while getting top tracks</title>
      <link>https://community.spotify.com/t5/Spotify-for-Developers/Help-with-Error-403-while-getting-top-tracks/m-p/6012379#M13551</link>
      <description>&lt;P&gt;According to &lt;A href="https://developer.spotify.com/documentation/web-api/reference/get-users-top-artists-and-tracks" target="_blank" rel="noopener"&gt;this documentation&lt;/A&gt;, you should add the&amp;nbsp;&lt;EM&gt;user-top-read&lt;/EM&gt; scope.&lt;/P&gt;</description>
      <pubDate>Wed, 17 Apr 2024 16:45:15 GMT</pubDate>
      <guid>https://community.spotify.com/t5/Spotify-for-Developers/Help-with-Error-403-while-getting-top-tracks/m-p/6012379#M13551</guid>
      <dc:creator>Ximzend</dc:creator>
      <dc:date>2024-04-17T16:45:15Z</dc:date>
    </item>
  </channel>
</rss>

