<?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>Thema "Authorization Code + PKCE flow returns invalid_grant despite verified-correct client config and a fresh code" in The Viessmann API</title>
    <link>https://community.viessmann.de/t5/The-Viessmann-API/Authorization-Code-PKCE-flow-returns-invalid-grant-despite/m-p/630988#M3546</link>
    <description>&lt;P&gt;Setup:&lt;BR /&gt;- Client type: public client, PKCE required (confirmed — see below), no client secret&lt;BR /&gt;- redirect_uri: &lt;A href="http://localhost:4200/" target="_blank"&gt;http://localhost:4200/&lt;/A&gt; (registered exactly as such in the developer portal, verified via the client editor UI)&lt;BR /&gt;- Scope requested: IoT User offline_access&lt;BR /&gt;- Grant: authorization_code with code_challenge_method=S256&lt;/P&gt;&lt;P&gt;Flow followed (per the Getting Started guide):&lt;BR /&gt;1. GET &lt;A href="https://iam.viessmann-climatesolutions.com/idp/v3/authorize?client_id=...&amp;amp;redirect_uri=http://localhost:4200/&amp;amp;response_type=code&amp;amp;scope=IoT+User+offline_access&amp;amp;code_challenge_method=S256&amp;amp;code_challenge=...&amp;amp;state=" target="_blank"&gt;https://iam.viessmann-climatesolutions.com/idp/v3/authorize?client_id=...&amp;amp;redirect_uri=http://localhost:4200/&amp;amp;response_type=code&amp;amp;scope=IoT+User+offline_access&amp;amp;code_challenge_method=S256&amp;amp;code_challenge=...&amp;amp;state=&lt;/A&gt;...&lt;BR /&gt;2. Logged in interactively in a real browser (reCAPTCHA passed normally).&lt;BR /&gt;3. Browser redirects to &lt;A href="http://localhost:4200/?code=...&amp;amp;state=" target="_blank"&gt;http://localhost:4200/?code=...&amp;amp;state=&lt;/A&gt;... as expected — state always matches.&lt;BR /&gt;4. POST &lt;A href="https://iam.viessmann-climatesolutions.com/idp/v3/token" target="_blank"&gt;https://iam.viessmann-climatesolutions.com/idp/v3/token&lt;/A&gt; with grant_type=authorization_code, client_id, redirect_uri, code, code_verifier.&lt;/P&gt;&lt;P&gt;Result every time: 400 {"e&lt;STRONG&gt;rror":"invalid_grant","error_description":"Invalid grant"&lt;/STRONG&gt;}&lt;/P&gt;&lt;P&gt;What I've ruled out, to save the next reader's time:&lt;BR /&gt;- PKCE math — independently recomputed BASE6and confirmed it matches the code_challengesent at step&amp;nbsp;1. - Code freshness / latency — set up a local irect URI that performs the token exchangeinline, in the same process, the instant the redirect lands (effectively zero delay between code issua exchange). Same invalid_grant.&lt;BR /&gt;- Client/redirect_uri mismatch — visually confirmed in the developer portal's client editor that the reg redirect URI is exactly &lt;A href="http://localhost:4n" target="_blank"&gt;http://localhost:4n&lt;/A&gt; both requests, and this was alreadyconfigured before any of these attempts (not something added reactively). - PKCE optionality — tried omitting code_cha entirely to see if this client accepts aplain authorization_code flow. Got a different, earlier error instead: invalid_request: "Code Challeng thrown at the /authorize step itself, befored. This confirms PKCE is mandatory for thisclient and that the client is otherwise reachable/valid. - Tested across 5 independent attempts with ier each time — same result every time.&lt;BR /&gt;Additional context: the same client_id can sccess token via the developer portal's own"try it" feature, and that token works fine against the IoT API. So the client itself is active and the client_id/scope combination is valid for APIthe browser-driven Authorization Code + PKCEexchange that fails.&lt;/P&gt;</description>
    <pubDate>Sat, 22 Aug 2026 18:20:10 GMT</pubDate>
    <dc:creator>Frank78</dc:creator>
    <dc:date>2026-08-22T18:20:10Z</dc:date>
    <item>
      <title>Authorization Code + PKCE flow returns invalid_grant despite verified-correct client config and a fresh code</title>
      <link>https://community.viessmann.de/t5/The-Viessmann-API/Authorization-Code-PKCE-flow-returns-invalid-grant-despite/m-p/630988#M3546</link>
      <description>&lt;P&gt;Setup:&lt;BR /&gt;- Client type: public client, PKCE required (confirmed — see below), no client secret&lt;BR /&gt;- redirect_uri: &lt;A href="http://localhost:4200/" target="_blank"&gt;http://localhost:4200/&lt;/A&gt; (registered exactly as such in the developer portal, verified via the client editor UI)&lt;BR /&gt;- Scope requested: IoT User offline_access&lt;BR /&gt;- Grant: authorization_code with code_challenge_method=S256&lt;/P&gt;&lt;P&gt;Flow followed (per the Getting Started guide):&lt;BR /&gt;1. GET &lt;A href="https://iam.viessmann-climatesolutions.com/idp/v3/authorize?client_id=...&amp;amp;redirect_uri=http://localhost:4200/&amp;amp;response_type=code&amp;amp;scope=IoT+User+offline_access&amp;amp;code_challenge_method=S256&amp;amp;code_challenge=...&amp;amp;state=" target="_blank"&gt;https://iam.viessmann-climatesolutions.com/idp/v3/authorize?client_id=...&amp;amp;redirect_uri=http://localhost:4200/&amp;amp;response_type=code&amp;amp;scope=IoT+User+offline_access&amp;amp;code_challenge_method=S256&amp;amp;code_challenge=...&amp;amp;state=&lt;/A&gt;...&lt;BR /&gt;2. Logged in interactively in a real browser (reCAPTCHA passed normally).&lt;BR /&gt;3. Browser redirects to &lt;A href="http://localhost:4200/?code=...&amp;amp;state=" target="_blank"&gt;http://localhost:4200/?code=...&amp;amp;state=&lt;/A&gt;... as expected — state always matches.&lt;BR /&gt;4. POST &lt;A href="https://iam.viessmann-climatesolutions.com/idp/v3/token" target="_blank"&gt;https://iam.viessmann-climatesolutions.com/idp/v3/token&lt;/A&gt; with grant_type=authorization_code, client_id, redirect_uri, code, code_verifier.&lt;/P&gt;&lt;P&gt;Result every time: 400 {"e&lt;STRONG&gt;rror":"invalid_grant","error_description":"Invalid grant"&lt;/STRONG&gt;}&lt;/P&gt;&lt;P&gt;What I've ruled out, to save the next reader's time:&lt;BR /&gt;- PKCE math — independently recomputed BASE6and confirmed it matches the code_challengesent at step&amp;nbsp;1. - Code freshness / latency — set up a local irect URI that performs the token exchangeinline, in the same process, the instant the redirect lands (effectively zero delay between code issua exchange). Same invalid_grant.&lt;BR /&gt;- Client/redirect_uri mismatch — visually confirmed in the developer portal's client editor that the reg redirect URI is exactly &lt;A href="http://localhost:4n" target="_blank"&gt;http://localhost:4n&lt;/A&gt; both requests, and this was alreadyconfigured before any of these attempts (not something added reactively). - PKCE optionality — tried omitting code_cha entirely to see if this client accepts aplain authorization_code flow. Got a different, earlier error instead: invalid_request: "Code Challeng thrown at the /authorize step itself, befored. This confirms PKCE is mandatory for thisclient and that the client is otherwise reachable/valid. - Tested across 5 independent attempts with ier each time — same result every time.&lt;BR /&gt;Additional context: the same client_id can sccess token via the developer portal's own"try it" feature, and that token works fine against the IoT API. So the client itself is active and the client_id/scope combination is valid for APIthe browser-driven Authorization Code + PKCEexchange that fails.&lt;/P&gt;</description>
      <pubDate>Sat, 22 Aug 2026 18:20:10 GMT</pubDate>
      <guid>https://community.viessmann.de/t5/The-Viessmann-API/Authorization-Code-PKCE-flow-returns-invalid-grant-despite/m-p/630988#M3546</guid>
      <dc:creator>Frank78</dc:creator>
      <dc:date>2026-08-22T18:20:10Z</dc:date>
    </item>
  </channel>
</rss>

