Getting 401 error when using Twitch OAuth token in my backend API

I’m trying to build my own API that calls Twitch endpoints but I’m running into authentication issues. The flow works like this: user gets redirected to Twitch auth page, I get the bearer token back, then I send that token to my backend API in the request header.

The problem is that when my API tries to use this token to make requests to Twitch, I always get a 401 unauthorized error. The weird thing is that the exact same token works perfectly when I test it in Postman. I can’t figure out what’s going wrong.

Here’s how I’m trying to verify the token in my backend:

public async Task<bool> CheckTokenValidity()
{
    var result = await httpClient.GetAsync("https://id.twitch.tv/oauth2/validate");
    return result.StatusCode == HttpStatusCode.OK;
}

And here’s how I set up my HttpClient with the auth headers:

public StreamingApiService(IHeaderDictionary requestHeaders)
{
    StringValues authToken;
    StringValues appClientId;
    var tokenExists = requestHeaders.TryGetValue("Authorization", out authToken);
    var clientIdExists = requestHeaders.TryGetValue("Client-id", out appClientId);

    httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Add("Accept", "application/json");

    if (tokenExists)
    {
        var cleanToken = authToken.ToString().Replace("Bearer", "");
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", cleanToken);
    }

    if (clientIdExists)
    {
        httpClient.DefaultRequestHeaders.Add("Client-ID", appClientId.ToString());
    }
}

Any ideas what could be causing this? Is there something wrong with how I’m handling the token?

I experienced a similar issue recently and found it was related to how the token was parsed. Specifically, your authToken.ToString().Replace("Bearer", "") method does not account for the space after “Bearer”, resulting in a leading space in the token. You should modify it to: csharp var cleanToken = authToken.ToString().Replace("Bearer ", "").Trim(); The .Trim() is crucial because StringValues may introduce extra whitespace when converted to a string. I spent hours troubleshooting this due to invisible whitespace characters. Additionally, ensure that the Client-ID header is being correctly set, as the Twitch API usually requires both the bearer token and client ID for most requests. Adding debug logs can help verify that both headers are present and correctly formatted before sending the request.

check if your token has the right scopes for that endpoint. twitch throws a 401 even with valid tokens when scopes don’t match what the API expects. also, that replace(“bearer”, “”) line looks sketchy - you might be leaving whitespace that’s breaking auth.

Had this exact problem a few months back - drove me nuts until I figured out it was HttpClient instantiation. You’re creating a new HttpClient in your service constructor, which messes with connection pooling and header management. Use IHttpClientFactory instead, or make sure you’re not disposing HttpClient too early. Also spotted another issue - you’re hitting the validate endpoint but not actually using the response properly. That endpoint returns token details you should check, not just the status code. Tokens can look valid but be expired or missing scopes. One more thing: check if your backend’s modifying the Authorization header during processing. I’ve seen middleware strip or change auth headers without warning. Log the exact header values right before the Twitch API call and compare them to what works in Postman.