I'm trying to integrate the Onshape API using OAuth2 authorization code flow but get a "invalid_grant", "Invalid authorization code" error when requesting an access token. I use a Flask application with ngrok for tunneling. The redirect_uri is verified but the issue persists. Details are below. Setup: Flask app running locally Ngrok tunneling (free tier) redirect_uri set to ngrok tunneling URL in both Flask and Onshape Developer Portal. Flow: User authorizes via Onshape authorization URL. Receive authorization code within a few seconds. Send token request to Onshape token endpoint with standard OAuth2 parameters. Receive 400 Bad Request with "invalid_grant", "Invalid authorization code". Environment: Python 3.11, Flask, ngrok 3.23.3, Onshape API. Tried fixing by verifying redirect_uri, testing with Postman, removing PKCE, and ensuring quick token requests, but the error remains. Relevant code (Python): from flask import Flask, request, redirect import requests import logging import os from dotenv import load_dotenv logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) load_dotenv() CLIENT_ID = os.getenv("ONSHAPE_CLIENT_ID") CLIENT_SECRET = os.getenv("ONSHAPE_CLIENT_SECRET").strip() REDIRECT_URI = "https://ad55-86-58-66-165.ngrok-free.app/oauthRedirect" app = Flask(__name__) access_token = None def get_access_token(code): global access_token token_url = "https://cad.onshape.com/oauth/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "authorization_code", "code": code, "redirect_uri": REDIRECT_URI, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET } logger.debug(f"Requesting token with data: {data}") response = requests.post(token_url, headers=headers, data=data, timeout=10) logger.debug(f"Token response: {response.status_code} - {response.text}") if response.status_code == 200: access_token = response.json()["access_token"] logger.debug(f"Access token obtained: {access_token}") return access_token logger.error(f"Token request failed: {response.text}") return None @app.route('/authorize') def authorize(): auth_url = f"https://cad.onshape.com/oauth/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope=OAuth2Read OAuth2Write" logger.debug(f"Redirecting to auth URL: {auth_url}") return redirect(auth_url) @app.route('/oauthRedirect') def oauth_redirect(): code = request.args.get('code') logger.debug(f"Received authorization code: {code}") if not code: return "Authorization failed. No code received.", 400 token = get_access_token(code) if not token: return "Failed to obtain access token. Check logs for details.", 500 return f"Authorization successful! Token obtained. You can close this window and return to the app. Token: {token}" Logs: DEBUG:__main__:Received authorization code: QZbnOvsHQUXXXVERVsUImTxr DEBUG:__main__:Requesting token with data: {'grant_type': 'authorization_code', 'code': 'QZbnOvsHQUXXXVERVsUImTxr', 'redirect_uri': 'https://ad55-86-58-66-165.ngrok-free.app/oauthRedirect', 'client_id': '3MW5AMQMQJEO3MQMVL57K56PNOOXDS4YI72J74I=', 'client_secret': 'B5X676JUGZEUJGIBNFW6TRPUVN354GQYCVHD5JQOTMI5PWIPOVCQ===='} DEBUG:urllib3.connectionpool:https://cad.onshape.com:443 "POST /oauth/token HTTP/1.1" 400 85 DEBUG:__main__:Token response: 400 - { "error" : "invalid_grant", "error_description" : "Invalid authorization code" } ERROR:__main__:Token request failed: { "error" : "invalid_grant", "error_description" : "Invalid authorization code" } Postman test with same parameters gives the same 400 response. Question: Has anyone encountered this issue with Onshape API or similar OAuth2 setups using ngrok? Could the ngrok free tier subdomain be the cause? Suggestions for fixing the invalid_grant error or alternative tunneling (e.g., localtunnel, Cloudflare Tunnel) are welcome! Continue reading...