PKCE code_verifier mismatch in Genesys Cloud SPA OAuth flow

Implementing Authorization Code flow with PKCE for a vanilla JS SPA. The code challenge is generated correctly using SHA-256, but the exchange to /oauth/token fails with 400 invalid_grant. The code_verifier matches the exact string used for the challenge, base64url encoded. Here’s the exchange payload:

{
 "grant_type": "authorization_code",
 "code": "AUTH_CODE_HERE",
 "code_verifier": "VERIFIER_HERE",
 "redirect_uri": "http://localhost:3000/callback"
}

Any idea why the server rejects the verifier?