<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: OAUTH-5 401 Unauthorized on /oauth/token with PKCE Exchange in Integration, Extension &amp; APIs</title>
    <link>https://community.qlik.com/t5/Integration-Extension-APIs/OAUTH-5-401-Unauthorized-on-oauth-token-with-PKCE-Exchange/m-p/2523188#M22349</link>
    <description>&lt;P&gt;Hey&amp;nbsp;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/315898"&gt;@AyeshaChhapra&lt;/a&gt;&amp;nbsp;, I'm seeing two missing things here.&lt;/P&gt;
&lt;P&gt;First, which could not cause the issue, you are missing "scope" parameter in the /oauth/token body request. You can use "user_default", but it depends on your requirements.&lt;/P&gt;
&lt;P&gt;Second, which could cause the issue, you are missing "credentaials": "include" in the&amp;nbsp;/oauth/token request. When you are redirected you should have some technical cookies and have to be attached.&lt;/P&gt;
&lt;P&gt;Below my code which is working correctly:&lt;/P&gt;
&lt;LI-CODE lang="javascript"&gt;const oAuthTokenRequestBody = {
            "grant_type": "authorization_code",
            "scope": "user_default",
            "code": oAuthCode,
            "redirect_uri": "https://localhost:8080/oauth_callback_custom.html",
            "code_verifier": localStorage.getItem('codeVerifier'),
            "client_id": "_clientId_"
        }
        const oAuthTokenRequest = await fetch('https://_tenant_.qlikcloud.com/oauth/token', {
          method: 'POST',
          body: JSON.stringify(oAuthTokenRequestBody),
          credentials: "include",
          headers: {
            "content-type": "application/json"
          }
        })&lt;/LI-CODE&gt;</description>
    <pubDate>Fri, 04 Jul 2025 10:52:51 GMT</pubDate>
    <dc:creator>alex_colombo</dc:creator>
    <dc:date>2025-07-04T10:52:51Z</dc:date>
    <item>
      <title>OAUTH-5 401 Unauthorized on /oauth/token with PKCE Exchange</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/OAUTH-5-401-Unauthorized-on-oauth-token-with-PKCE-Exchange/m-p/2522970#M22341</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Hi Qlik Community,&lt;/P&gt;&lt;P&gt;I’m working on implementing OAuth2 Authorization Code Flow with PKCE in a React SPA for Qlik Cloud, but I’m running into a 401 error when attempting to exchange my authorization code for tokens.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Error Response&lt;/P&gt;&lt;P&gt;When I POST to /oauth/token, I receive:&lt;/P&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;{&lt;BR /&gt;"errors": [&lt;BR /&gt;{&lt;BR /&gt;"title": "Unauthorized",&lt;BR /&gt;"code": "OAUTH-5",&lt;BR /&gt;"status": "401"&lt;BR /&gt;}&lt;BR /&gt;],&lt;BR /&gt;"traceId": "e6f75ad8bb6ac27f4c5992feb440d713"&lt;BR /&gt;}&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Code Snippet&lt;/P&gt;&lt;P&gt;Here is my token-exchange function using axios:&lt;/P&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;async&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt; &lt;SPAN&gt;fetchTokens&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;const&lt;/SPAN&gt; &lt;SPAN&gt;params&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;URLSearchParams&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;search&lt;/SPAN&gt;&lt;SPAN&gt;);&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;const&lt;/SPAN&gt; &lt;SPAN&gt;code&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;params&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;get&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;"code"&lt;/SPAN&gt;&lt;SPAN&gt;);&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;const&lt;/SPAN&gt; &lt;SPAN&gt;verifier&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;sessionStorage&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;getItem&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;"pkce_verifier"&lt;/SPAN&gt;&lt;SPAN&gt;);&lt;/SPAN&gt;&lt;/DIV&gt;&lt;BR /&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;const&lt;/SPAN&gt; &lt;SPAN&gt;body&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;URLSearchParams&lt;/SPAN&gt;&lt;SPAN&gt;({&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;grant_type&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;"authorization_code"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;client_id&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;meta&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;env&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;VITE_QLIK_CLIENT_ID&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;code_verifier&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;verifier&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;code&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;redirect_uri&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;meta&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;env&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;VITE_REDIRECT_URI&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;console&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;log&lt;/SPAN&gt;&lt;SPAN&gt;({&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;grant_type&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;"authorization_code"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;client_id&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;meta&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;env&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;VITE_QLIK_CLIENT_ID&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;code_verifier&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;verifier&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;code&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;redirect_uri&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;meta&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;env&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;VITE_REDIRECT_URI&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;const&lt;/SPAN&gt; &lt;SPAN&gt;response&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;await&lt;/SPAN&gt; &lt;SPAN&gt;fetch&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;`&lt;/SPAN&gt;&lt;SPAN&gt;${&lt;/SPAN&gt;&lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;meta&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;env&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;VITE_TENANT_URI&lt;/SPAN&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;SPAN&gt;/oauth/token`&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;method&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;"POST"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;headers&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;"Content-Type"&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;"application/x-www-form-urlencoded"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;body&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; );&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;const&lt;/SPAN&gt; &lt;SPAN&gt;data&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;await&lt;/SPAN&gt; &lt;SPAN&gt;response&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;json&lt;/SPAN&gt;&lt;SPAN&gt;();&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;setAuthTokens&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;);&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;navigate&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;"/"&lt;/SPAN&gt;&lt;SPAN&gt;, { &lt;/SPAN&gt;&lt;SPAN&gt;replace&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;true&lt;/SPAN&gt;&lt;SPAN&gt; });&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; }&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Wed, 02 Jul 2025 09:30:12 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/OAUTH-5-401-Unauthorized-on-oauth-token-with-PKCE-Exchange/m-p/2522970#M22341</guid>
      <dc:creator>AyeshaChhapra</dc:creator>
      <dc:date>2025-07-02T09:30:12Z</dc:date>
    </item>
    <item>
      <title>Re: OAUTH-5 401 Unauthorized on /oauth/token with PKCE Exchange</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/OAUTH-5-401-Unauthorized-on-oauth-token-with-PKCE-Exchange/m-p/2522988#M22342</link>
      <description>&lt;P&gt;Hi there!&lt;/P&gt;
&lt;P&gt;A 401 "Unauthorized" error (code "OAUTH-5") during the token exchange step of the OAuth2 Authorization Code Flow with PKCE typically indicates an issue with the credentials or parameters being sent to the /oauth/token endpoint. Given your code snippet and the error, here's a breakdown of common causes and how to troubleshoot them:&lt;/P&gt;
&lt;P&gt;Common Causes for OAUTH-5 (401 Unauthorized)&lt;BR /&gt;Incorrect client_id: This is a very frequent culprit. Double-check that import.meta.env.VITE_QLIK_CLIENT_ID exactly matches the Client ID you obtained when registering your SPA in Qlik Cloud. Any typo or mismatch will lead to a 401.&lt;/P&gt;
&lt;P&gt;Mismatched redirect_uri: The redirect_uri sent in the token exchange request (import.meta.env.VITE_REDIRECT_URI) must precisely match the redirect_uri that was used in the initial authorization request and, crucially, the redirect_uri configured for your client in Qlik Cloud. Even a trailing slash difference can cause this error.&lt;/P&gt;
&lt;P&gt;Invalid code: The authorization code you received from the authorization server is single-use and has a short lifespan.&lt;/P&gt;
&lt;P&gt;Expired Code: If there's a significant delay between getting the code and exchanging it, it might have expired.&lt;/P&gt;
&lt;P&gt;Used Code: If you're trying to exchange the same code multiple times (e.g., due to a page refresh or re-rendering), it will be invalid after the first successful exchange.&lt;/P&gt;
&lt;P&gt;Mismatched code_verifier: The code_verifier sent in the token exchange must exactly match the original code_verifier that was used to generate the code_challenge for the initial authorization request.&lt;/P&gt;
&lt;P&gt;Storage Issue: Ensure sessionStorage.getItem("pkce_verifier") is correctly retrieving the exact verifier that was stored. Any modification, truncation, or failure to retrieve it will cause a mismatch.&lt;/P&gt;
&lt;P&gt;Timing: The verifier should be stored before redirecting to the authorization endpoint.&lt;/P&gt;
&lt;P&gt;Incorrect Content-Type Header: While your code snippet correctly sets "Content-Type": "application/x-www-form-urlencoded", it's worth double-checking that no other part of your application or any proxy is inadvertently changing this. The body being a URLSearchParams object is correct for this content type.&lt;/P&gt;
&lt;P&gt;Qlik Cloud Application Configuration:&lt;/P&gt;
&lt;P&gt;PKCE Enabled: Ensure that your OAuth client in Qlik Cloud is configured to use PKCE. While the code_verifier implies you're attempting to use it, the server-side configuration needs to align.&lt;BR /&gt;&lt;A href="https://www.marykayintouches.com" target="_self"&gt;&lt;FONT size="1 2 3 4 5 6 7" color="#FFFFFF"&gt;marykayintouch&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Grant Types: Verify that "Authorization Code" is an allowed grant type for your client in Qlik Cloud.&lt;/P&gt;</description>
      <pubDate>Wed, 02 Jul 2025 11:36:47 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/OAUTH-5-401-Unauthorized-on-oauth-token-with-PKCE-Exchange/m-p/2522988#M22342</guid>
      <dc:creator>daisy64</dc:creator>
      <dc:date>2025-07-02T11:36:47Z</dc:date>
    </item>
    <item>
      <title>Re: OAUTH-5 401 Unauthorized on /oauth/token with PKCE Exchange</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/OAUTH-5-401-Unauthorized-on-oauth-token-with-PKCE-Exchange/m-p/2523188#M22349</link>
      <description>&lt;P&gt;Hey&amp;nbsp;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/315898"&gt;@AyeshaChhapra&lt;/a&gt;&amp;nbsp;, I'm seeing two missing things here.&lt;/P&gt;
&lt;P&gt;First, which could not cause the issue, you are missing "scope" parameter in the /oauth/token body request. You can use "user_default", but it depends on your requirements.&lt;/P&gt;
&lt;P&gt;Second, which could cause the issue, you are missing "credentaials": "include" in the&amp;nbsp;/oauth/token request. When you are redirected you should have some technical cookies and have to be attached.&lt;/P&gt;
&lt;P&gt;Below my code which is working correctly:&lt;/P&gt;
&lt;LI-CODE lang="javascript"&gt;const oAuthTokenRequestBody = {
            "grant_type": "authorization_code",
            "scope": "user_default",
            "code": oAuthCode,
            "redirect_uri": "https://localhost:8080/oauth_callback_custom.html",
            "code_verifier": localStorage.getItem('codeVerifier'),
            "client_id": "_clientId_"
        }
        const oAuthTokenRequest = await fetch('https://_tenant_.qlikcloud.com/oauth/token', {
          method: 'POST',
          body: JSON.stringify(oAuthTokenRequestBody),
          credentials: "include",
          headers: {
            "content-type": "application/json"
          }
        })&lt;/LI-CODE&gt;</description>
      <pubDate>Fri, 04 Jul 2025 10:52:51 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/OAUTH-5-401-Unauthorized-on-oauth-token-with-PKCE-Exchange/m-p/2523188#M22349</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2025-07-04T10:52:51Z</dc:date>
    </item>
  </channel>
</rss>

