I'm using the Graph API via HTTP. I need to filter on all users that have a signInType of "emailAddress".
I'm using this select:
https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities
which returns:
"value":
[
{
"displayName": "Alice User",
"accountEnabled": true,
"id": "abcdef01-0aac-8890-5454-1234567890ab",
"identities": [
{
"signInType": "emailAddress",
"issuer": "mytenant.onmicrosoft.com",
"issuerAssignedId": "alice.user@mydomain.xyz"
},
{
"signInType": "userPrincipalName",
"issuer": "mytenant.onmicrosoft.com",
"issuerAssignedId": "abcdef01-0aac-8890-5454-1234567890ab@mytenant.onmicrosoft.com"
}
]
},
{
"displayName": "George User",
"accountEnabled": true,
"id": "12345678-0bb2-430b-8208-abcdefabcdef",
"identities": [
{
"signInType": "emailAddress",
"issuer": "mytenant.onmicrosoft.com",
"issuerAssignedId": "george.user@mydomain.xyz"
},
{
"signInType": "userPrincipalName",
"issuer": "mytenant.onmicrosoft.com",
"issuerAssignedId": "12345678-0bb2-430b-8208-abcdefabcdef@mytenant.onmicrosoft.com"
}
]
},
...
]
When I add this filter to the query, I'm getting an error:
https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities&$filter=identities/any(id:id/signInType eq 'emailAddress')
{
"error": {
"code": "Request_BadRequest",
"message": "Unsupported property or property value or combination of property and operation occured",
"innerError": {
"date": "2025-04-17T20:00:20",
"request-id": "841c2d30-b453-4b2c-972d-fff6e26ac60d",
"client-request-id": "841c2d30-b453-4b2c-972d-fff6e26ac60d"
}
}
}
I have tried various combinations of the filter, all with no success. I believe it's because identities is itself a collection.
This SO post also appears to be filtering on identities in the same manner (the OP states their first approach works): Microsoft Graph API: oddity with searching a user by identity
However, it's not working for me so I must be doing something wrong.
How can I filter on the nested identities collection so that I can query just users that have a "signInType": "emailAddress"?
Thanks.
There is no supported way in Microsoft Graph API (v1.0 or beta) yet, to directly query users based only on the signInType (e.g., emailAddress) in the identities property of Azure AD B2C Users .
NOTE: Microsoft Graph API does not support filtering directly on nested collections like identities using the $filter parameter.
I got the same error message for the below query:
GET https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities&$filter=identities/any(id:id/signInType eq 'emailAddress')

Microsoft Graph API only supports Filtering for entries with a signInType of userName or emailAddress requires a valid issuer and issuerAssignedId but ignores the issuer value. This is by design. For more details Refer this MsDoc.
Use below query for listing the users:
GET https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities
Response:

For fetching the user whose signInType : emailAddress using valid issuer and issuerAssignedId use below query:
GET https://graph.microsoft.com/v1.0/users?$filter=identities/any(c:c/issuerAssignedId eq '<issuerAssingedId>' and c/issuer eq '<issuer>')
Response:

As listing of users without valid issuer and issuerAssignedId is not supported by Microsoft Graph API (via HTTP), So as a Workaround, To fetch those users by filtering it on signInType: 'emailAddress .
Use below Python code:
import requests
# Replace 'access_token' with your actual access token
access_token = '<your-access-token>'
url = 'https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities'
headers = {
'Authorization': f'Bearer {access_token}'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
users = response.json().get('value', [])
filtered_users = []
for user in users:
identities = user.get('identities', [])
for identity in identities:
if (
identity.get('signInType') == 'emailAddress' and
identity.get('issuer') and
identity.get('issuerAssignedId')
):
filtered_users.append({
'displayName': user.get('displayName'),
'id': user.get('id'),
'emailAddress': identity.get('issuerAssignedId'),
'issuer': identity.get('issuer')
})
break # If one matching identity is found, no need to check others
print("Filtered users:")
for user in filtered_users:
print(user)
else:
print(f"Request failed with status code {response.status_code}")
print(response.text)
Response:

Reference: