Question about PKCE Flow

Is there anyone who can tell me why I keep getting a 401 error when using the PKCE Flow of the FFLogs API? I’m not sure if it’s allowed to ask this kind of question in this channel. If I’ve done anything wrong, please let me know. Thank you. Here are some of my parameters, with sensitive ones hidden.

code_challenge: oZ4lOfkDGBIm-UzH3X_YDQj6-dfEtBwmc4XS49NzLW0
code_verifier: DaePuze24AUAq7NBKHfnGcSJUyjvpFzBDVx6yDVcHKTJHGYvnJAaxj5aDktJp3WVATDaHBL4otnMhuBfP0ZvJW2MlgxpAeDdXSSe0skpov8rggOo

I ensure that the client_id, redirect_uri, state, and response_type I passed are filled in accordance with the documentation. The oauth/authorize interface redirected normally, and I obtained the code and verified the state. However, I got a 401 error when making a request to the oauth/token endpoint. I’m using JavaScript’s fetch for the requests.

Code fragments:
generate code_hallenge and code verifier

const sha256 = async (plainText: string) => {
  const encoder = new TextEncoder()
  const data = encoder.encode(plainText)
  const hashBuffer = await crypto.subtle.digest('SHA-256', data)
  const hashArray = Array.from(new Uint8Array(hashBuffer))
  const hashHex = hashArray
    .map((buffer) => buffer.toString(16).padStart(2, '0'))
    .join('')
  return { hashArray, hashHex }
}

const base64UrlEncode = (hashArray: number[]) => {
  return btoa(String.fromCharCode.apply(null, hashArray))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '')
}

export const generatePKCE = async () => {
  const codeVerifier = randomLenString(43, 128)
  const { hashArray, hashHex } = await sha256(codeVerifier)
  const codeChallenge = base64UrlEncode(hashArray)
  const codeVerifierHex = hashHex
  return { codeChallenge, codeVerifier, codeVerifierHex }
}

authorize

const url =
      env.FFLOGS_AUTHORIZE_URL +
      '?client_id=' +
      env.FFLOGS_CLIENT_ID +
      '&code_challenge=' +
      codeChallenge +
      '&code_challenge_method=S256' +
      '&state=' +
      state +
      '&redirect_uri=' +
      encodeURIComponent(env.FFLOGS_REDIRECT_URI) +
      '&response_type=code'

    window.location.href = url

request token

await fetch(env.FFLOGS_TOKEN_URL, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: new URLSearchParams({
            client_id: env.FFLOGS_CLIENT_ID,
            code_verifier: codeVerifierHex,
            redirect_uri: encodeURIComponent(env.FFLOGS_REDIRECT_URI),
            grant_type: 'authorization_code',
            code: code,
          }),
        })