C# .NET Spotify API Token Authentication Issue with User Scopes

Getting 401 Error When Accessing Spotify User Profile Endpoint

I’m working on a C# application that needs to get user data from Spotify’s API. I can generate an access token successfully, but when I try to call the user profile endpoint that needs specific permissions, I keep getting a 401 error.

The Problem: My token works fine for basic requests, but fails when I try to access user data that requires user-read-private and user-read-email permissions.

My Current Implementation

Here’s how I’m requesting the token:

public async Task<SpotifyApiResponse> RequestAccessTokenWithPermissions(SpotifyCredentials credentials, string[] permissions)
{
    var permissionList = string.Join(" ", permissions);
    
    var formData = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("grant_type", "client_credentials"), 
        new KeyValuePair<string, string>("scope", permissionList)
    });

    var credentialString = $"{credentials.AppId}:{credentials.AppSecret}";
    var encodedCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentialString));

    var httpRequest = new HttpRequestMessage(HttpMethod.Post, _apiTokenUrl)
    {
        Headers = { Authorization = new AuthenticationHeaderValue("Basic", encodedCredentials) },
        Content = formData
    };

    var apiResponse = await _client.SendAsync(httpRequest);

    if (!apiResponse.IsSuccessStatusCode)
    {
        var error = await apiResponse.Content.ReadAsStringAsync();
        throw new Exception($"Token request failed: {apiResponse.StatusCode} - {error}");
    }

    var responseData = await apiResponse.Content.ReadAsStringAsync();
    return JsonSerializer.Deserialize<SpotifyApiResponse>(responseData, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}

And my command handler:

public class FetchSpotifyUserToken : IRequest<ApiResponseDto>
{
    public string AppId { get; set; }
    public string AppSecret { get; set; }
}

public class FetchSpotifyUserTokenHandler : IRequestHandler<FetchSpotifyUserToken, ApiResponseDto>
{
    private readonly ISpotifyApiService _apiService;

    public FetchSpotifyUserTokenHandler(ISpotifyApiService apiService)
    {
        _apiService = apiService;
    }

    public async Task<ApiResponseDto> Handle(FetchSpotifyUserToken command, CancellationToken token)
    {
        try
        {
            var credentials = new SpotifyCredentials
            {
                AppId = command.AppId,
                AppSecret = command.AppSecret
            };

            var requiredPermissions = new[]
            {
                "user-read-private",
                "user-read-email"
            };
            
            Console.WriteLine($"Getting token for permissions: {string.Join(", ", requiredPermissions)}");
            
            var authToken = await _apiService.RequestAccessTokenWithPermissions(credentials, requiredPermissions);

            return new ApiResponseDto()
            {
                StatusCode = (int)HttpStatusCode.OK,
                Message = "Authentication token created successfully.",
                Data = authToken
            };
        }
        catch (Exception error)
        {
            return new ApiResponseDto()
            {
                StatusCode = (int)HttpStatusCode.InternalServerError,
                Message = error.Message,
                Data = null
            };
        }
    }
}

I’m pretty confused about what I’m doing wrong here. Any ideas what might be causing this issue?

client_credentials won’t work for user profile endpoints - that’s why you’re getting a 401. You need authorization_code flow instead, which means the user has to log in and authorize your app first. client_credentials is only for app-level data, not personal user info.

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.