Question: I created below app to send mail using Graph API  I used Client Credential flow to send mail, but I keep getting 401 error. Is there anything that needs to be changed in the API permission on Azure or in the code? Is there a way I can send mail using delegated access without an interactive session? import requests import msal client_id = 'bdxxx' tenant_id = '97xxx' client_secret = 'Ltxxxxxx' authority = f'https://login.microsoftonline.com/{tenant_id}' scope = ['https://graph.microsoft.com/.default'] graph_url = 'https://graph.microsoft.com/v1.0' sender_email = 'lxxx@gmail.com' def get_access_token(): try: client = msal.ConfidentialClientApplication(client_id, authority=authority, client_credential=client_secret) token_result = client.acquire_token_for_client(scopes=scope) if "access_token" in token_result: return f"Bearer {token_result['access_token']}" else: raise Exception(f"Failed to obtain access token: {token_result}") except Exception as e: print(f"Exception: {e}") return None if __name__ == '__main__': access_token = get_access_token() print(f'Access token: {access_token}') if not access_token: print("Access token retrieval failed. Exiting.") exit() headers = { 'Authorization': access_token, 'Content-Type': 'application/json' } email_message = { "message": { "subject": "Test Email", "body": { "contentType": "HTML", "content": "Email body" }, "toRecipients": [ { "emailAddress": { "address": "lxx@gmail.com" } } ], "from": { "emailAddress": { "address": 'csxxx@gmail.com' } } }, "saveToSentItems": "false" } response = requests.post( f"{graph_url}/users/{sender_email}/sendMail", json=email_message, headers=headers ) print(f'{response.status_code} {response.text}') 

Answer: The error usually occurs if you using  ConfidentialClientApplication to send mail and granted delegated type API permission to the Microsoft Entra ID application. Hence to resolve the error, you need to grant application type API permission to the Microsoft Entra ID application. Refer this MsDoc Make sure to grant admin consent:  Now I am able to send mail successfully: import requests import msal client_id = 'ClientID' tenant_id = 'TenantID' client_secret = 'Secret' authority = f'https://login.microsoftonline.com/{tenant_id}' scope = ['https://graph.microsoft.com/.default'] graph_url = 'https://graph.microsoft.com/v1.0' sender_email = 'xxx' def get_access_token(): try: client = msal.ConfidentialClientApplication(client_id, authority=authority, client_credential=client_secret) token_result = client.acquire_token_for_client(scopes=scope) if "access_token" in token_result: return f"Bearer {token_result['access_token']}" else: raise Exception(f"Failed to obtain access token: {token_result}") except Exception as e: print(f"Exception: {e}") return None if __name__ == '__main__': access_token = get_access_token() print(f'Access token: {access_token}') if not access_token: print("Access token retrieval failed. Exiting.") exit() headers = { 'Authorization': access_token, 'Content-Type': 'application/json' } email_message = { "message": { "subject": "Test Email", "body": { "contentType": "HTML", "content": "Email body" }, "toRecipients": [ { "emailAddress": { "address": "xxx" } } ], "from": { "emailAddress": { "address": 'xxx' } } }, "saveToSentItems": "false" } response = requests.post( f"{graph_url}/users/{sender_email}/sendMail", json=email_message, headers=headers ) print(f'{response.status_code} {response.text}')    Make sure to assign O365 license to the user. And if you are making use of personal Microsoft user account to send mail, then it required Mail.Send delegated API permission which doesn't work with  ConfidentialClientApplication For personal Microsoft user account, you need to make use of /me that is https://graph.microsoft.com/v1.0/me/sendMail endpoint and make use of any user interactive flow.