I'm trying to use the send mail API using the Microsoft Graph API and I've tried it using the Graph API explorer and it's working fine but when I try to get the Token on Postman and get the token I get an error. when I use the token from the explorer on my code it works fine but when using mine from Postman I got this error :
Response content: b'{"error":{"code":"BadRequest","message":"/me request is only valid with delegated authentication flow.","innerError":{"date":"2024-05-28T11:34:23","request-id":"","client-request-id":""}}}'
import requests
url = 'https://graph.microsoft.com/v1.0/me/sendMail'
access_token = ''
headers = {
'Authorization': 'Bearer {}'.format(access_token),
'Content-Type': 'application/json'
}
email = {
"message": {
"subject": "PYTHON",
"body": {
"contentType": "HTML",
"content": ""
},
"toRecipients": [
{
"emailAddress": {
"address": "hamzaha@watira.ai"
}
}
]
},
"saveToSentItems": "true"
}
response = requests.post(url, headers=headers, json=email)
if response.status_code == 202:
print("Email sent successfully.")
else:
print("Failed to send email. Status code:", response.status_code)
print("Response content:", response.content)
The error occurred as /me
endpoint supports only delegated flows like authorization code flow that involves user interaction, but client credentials is app-only flow.
Initially, I too got same error when I run the code passing token generated with client credentials flow like this:
import requests
url = 'https://graph.microsoft.com/v1.0/me/sendMail'
access_token = 'token'
headers = {
'Authorization': 'Bearer {}'.format(access_token),
'Content-Type': 'application/json'
}
email = {
"message": {
"subject": "PYTHON",
"body": {
"contentType": "HTML",
"content": ""
},
"toRecipients": [
{
"emailAddress": {
"address": "sridevi.mxxx1@gmail.com"
}
}
]
},
"saveToSentItems": "true"
}
response = requests.post(url, headers=headers, json=email)
if response.status_code == 202:
print("Email sent successfully.")
else:
print("Failed to send email. Status code:", response.status_code)
print("Response content:", response.content)
Response:
To resolve the error, you need to either switch to delegated flows like authorization code flow for generating token or use /users/userID
endpoint with client credentials token.
In my case, I granted Mail.Send
permission of Application type in my app registration like this:
Now, I generated token using client credentials flow via Postman as below:
POST https://login.microsoftonline.com/tenantId/oauth2/v2.0/token
grant_type:client_credentials
client_id: appId
client_secret: secret
scope: https://graph.microsoft.com/.default
Response:
When I used this token in below Python code by changing endpoint to /users/userID
, I got response like this:
import requests
url = 'https://graph.microsoft.com/v1.0/users/userId/sendMail'
access_token = 'token'
headers = {
'Authorization': 'Bearer {}'.format(access_token),
'Content-Type': 'application/json'
}
email = {
"message": {
"subject": "PYTHON",
"body": {
"contentType": "HTML",
"content": ""
},
"toRecipients": [
{
"emailAddress": {
"address": "sridevi.mxxx1@gmail.com"
}
}
]
},
"saveToSentItems": "true"
}
response = requests.post(url, headers=headers, json=email)
if response.status_code == 202:
print("Email sent successfully.")
else:
print("Failed to send email. Status code:", response.status_code)
print("Response content:", response.content)
Response:
You can find User ID of sender in Azure Portal like this:
This /me
endpoint works in Graph Explorer as it uses delegated permissions of signed-in user. If you prefer switching to delegated flows for generating tokens, refer this similar SO thread I previously answered that includes token generation with authorization code flow:
azure active directory - Call microsoft graph - Stack Overflow