PKCE code_verifier mismatch in SPA auth flow

Stuck on the final step of the Authorization Code flow with PKCE. I generate the code_challenge in the browser using SHA-256 and send it to the auth endpoint. The redirect returns the code. When I POST to /api/v2/oauth/token with the code_verifier, I get a 400 Invalid grant. The verifier matches the challenge in my console logs, but the server rejects it. Here’s the token request payload:

{
 "grant_type": "authorization_code",
 "code": "xyz123",
 "code_verifier": "abc789",
 "redirect_uri": "https://myapp.local/callback"
}

Is there a specific encoding issue with the verifier string?