Help Wizard

Step 1



Please see below the most popular frequently asked questions.

Loading article...

Loading faqs...


Ongoing Issues

Please see below the current ongoing issues which are under investigation.

Loading issue...

Loading ongoing issues...


Help with Error 403 while getting top tracks

Help with Error 403 while getting top tracks



const clientId = "...";
const params = new URLSearchParams(;
const code = params.get("code");

if (!code) {
} 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 = `${params.toString()}`;
function generateCodeVerifier(length: number) {
    let text = '';
    let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    for (let i = 0; i < 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, [ Uint8Array(digest)]))
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=+$/, '');

export async function getAccessToken(clientId: string, code: string): Promise<string> {
    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("", {
        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<UserProfile> {
    const result = await fetch("", {
        method: "GET", headers: { Authorization: `Bearer ${token}` }

    return await result.json();

async function fetchTracks(token: string): Promise<any> {
    const result = await fetch("", {
        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);
    document.getElementById("id")!.innerText =;
    document.getElementById("email")!.innerText =;
    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)';




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 "" after logging in I get the tracks data just fine. Why is the call not working in my app?

1 Reply

According to this documentation, you should add the user-top-read scope.

Suggested posts