Why is the token endpoint rejecting my authorization code with a 400 Bad Request? We’re implementing the Authorization Code flow with PKCE for a new React SPA. The redirect works fine, we capture the code, and we hit https://api.mypurecloud.com/oauth/token with the right grant_type and redirect_uri. The error payload says invalid_grant: Code challenge method not supported. We are definitely sending the code_verifier in the body.
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=AUTH_CODE_HERE&redirect_uri=http://localhost:3000/callback&client_id=OUR_CLIENT_ID&code_verifier=VERIFIER_STRING_HERE
The verifier is generated with SHA-256 and base64url encoded. We’ve double-checked the encoding logic against the RFC. The challenge was sent during the auth request. Is there a specific setting in the Genesys Cloud application configuration that needs to be toggled for PKCE to actually work? The docs are vague on whether implicit grant apps can even do this.
The error message Code challenge method not supported is misleading. It usually means your code_verifier doesn’t match the code_challenge sent in the initial auth request, or you’re sending it in the wrong format. Genesys Cloud requires S256 for the challenge method.
Here’s how I handle it in C#. The key is ensuring the verifier is a high-entropy random string and the challenge is the base64url-encoded SHA256 hash of that verifier. No padding, no standard base64.
using System.Security.Cryptography;
using System.Text;
public static string GenerateCodeVerifier(int length = 64)
{
var randomBytes = new byte[length];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(randomBytes);
return Convert.ToBase64String(randomBytes)
.TrimEnd('=')
.Replace('+', '-')
.Replace('/', '_');
}
public static string GenerateCodeChallenge(string codeVerifier)
{
using var sha256 = SHA256.Create();
var hashBytes = sha256.ComputeHash(Encoding.ASCII.GetBytes(codeVerifier));
return Convert.ToBase64String(hashBytes)
.TrimEnd('=')
.Replace('+', '-')
.Replace('/', '_');
}
When you exchange the code, make sure the code_verifier in the POST body to /oauth/token matches the one used to generate the challenge. Don’t reuse verifiers. Each auth flow needs a fresh pair.
Also, check your grant_type. It must be authorization_code. If you’re using client_credentials, PKCE isn’t involved, and you’ll get weird errors. The docs say “The code_verifier parameter must be present if code_challenge was present in the authorization request.” If your frontend generated the challenge but your backend sends a different verifier, the server rejects it.
I’ve seen this fail when teams copy-paste the verifier from a debugger and manually type it into Postman for testing. Whitespace kills it. Use the exact string.
If you’re using the .NET SDK for this, look at PlatformClient.Auth methods. But for SPA flows, direct HTTP calls are often clearer. Just ensure your HttpClient doesn’t modify the body. Use StringContent with application/x-www-form-urlencoded.