When making calls to get user centric data from the Microsoft Graph API the documentation tells us we can use either the users (Graph) id or the users UPN (Active Directory User Principal Name)
For example, to get the details of a specific user
GET /users/{id|userPrincipalName}
To get mail messages for a specific user
GET /users/{id|userPrincipalName}/messages
The user id is the most reliable to use if you have it available. Usually, you will only have this if you have obtained it through previous calls to the Graph API. The UPN is something that you may have more readily have available, this is the value entered by the user when they authenticate with Azure Active Directory and is typically also the users primary email address e.g. cdwyer@opsdev.work
This makes it easier to get user information from the Graph if you just have the users email address. Ok, back that up a second. I said it makes it easy if you have the users email address, but that isn’t always the case, you see while UPN is often the users primary email address this isn’t always the case. A user may also have many alias email addresses. According to the Microsoft Graph documentation you can only use the UPN. So, while a user may be known by multiple different alias email addresses you have to have the one that matches up with the users UPN. See why I said using the Graph Id is more reliable if you have it?
Let’s take a look at this in action. Here I’ve got a user configured with a UPN different to the primary email address.
UPN: cdwyer@opsdev.work
Email: cdwyer@opsdev.onmicrosoft.com
If we make a call to the Graph API to get the user by UPN we are successful
https://graph.microsoft.com/v1.0/users/cdwyer@opsdev.work

If we now try to make that same call but use the primary mail address instead of the UPN then we won’t be able to find the user.
https://graph.microsoft.com/v1.0/users/cdwyer@opsdev.onmicrosoft.com

This would be a pretty boring article if I just ended it here because this is what the documentation tells us and what we expect. Here’s where things take an interesting turn, instead of getting the user object, let’s try to get the mail messages for this user.
If we make a call to the Graph API to get the users messages by UPN we are successful (no surprises here)
https://graph.microsoft.com/v1.0/users/cdwyer@opsdev.work/messages

Now let’s try that call using the users primary mail address that just failed trying to get the user object.
https://graph.microsoft.com/v1.0/users/cdwyer@opsdev.onmicrosoft.com/messages

That wasn’t expected, what is going on here! We can’t get the user object by the email address, yet we can traverse the Graph and magically get the messages 🤯. Ok, pack my grey matter back into my skull, maybe this magic is in the messages endpoint because it deals with mail and it is rather awesome that we can get to a user’s messages using either the UPN or email address. Let’s see what happens on a different endpoint such as getting a user’s To Do tasks.
https://graph.microsoft.com/v1.0/users/cdwyer@opsdev.onmicrosoft.com/todo/lists

Let’s push this one step further. What if we didn’t use the UPN, or the primary email address? What if we try using an alias address for the user?
https://graph.microsoft.com/v1.0/users/cams-alias@opsdev.work/messages

Mind blown again. So, it seems WE CAN’T get the user object by anything other than Graph Id or UPN, but WE CAN get at the user’s data (at least messages and to do lists using primary email address or an alias email address). This is not documented and therefore not supported by Microsoft (as of July 2023) but it seems like the hard work has been done in the service to allow this to happen. This would be immensely powerful if it were supported. It means when working with email we don’t have to go to the overhead of looking up and resolving all email addresses to discover the user UPN or Graph Id before being able to get a handle on the user’s messages.
Leave a comment